function call_price = binom_option(S0,K,T,r,sigma,N)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Inputs: S0 -- initial underlying price
%        K -- strike 
%        T -- Maturity
%        r -- interest rate
%        sigme -- volatility
%        N -- number of days
%Output: call_price
%Method: Binomial Tree
%Example: 
%S0=5;K=10;T=1;r=0.06;sigma=0.3;N=256;
%binom_option(S0,K,T,r,sigma,N)
% question : optimize algorithm; write a new one: switch option type
% call/put
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (nargin < 1)
S0=5;K=6;T=1;r=0.06;sigma=0.3;N=5;
end
dt=T/N; % step size
A=0.5*(exp(-r*dt)+exp((r+sigma^2)*dt));
u=A + sqrt(A^2-1); % appreciation rate
d=1/u;% depreciation rate
q=(exp(r*dt)-d)/(u-d); % risk neutral prob
S = zeros(1,N); % initialize
C = cell(1,N); % initialize, cell type

% step I: forward calculation: generate stock path 
for i = 1:N
S(i) = S0*u^i*d^(N-i);
end

% Step II: Backward pricing: calculate call option pricing
C{N} = max(S-K,0);
for i = N:-1:2
    c = C{i};
    sup = c(1:length(C{i})-1);
    sdown = c(2:length(C{i}));
    C{i-1} = exp(-r*dt)*(q*sup+(1-q)*sdown);
end

call_price = C{1};
end